package icu.qx.gbs.service.impl;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Queue;
import java.util.stream.Collectors;

import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.security.utils.SecurityUtils;
import icu.qx.gbs.domain.GbsBomMaterial;
import icu.qx.gbs.domain.PbsProcedureMaterial;
import icu.qx.gbs.feign.PbsProcedureMaterialFeign;
import icu.qx.gbs.service.IGbsBomMaterialService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import icu.qx.gbs.mapper.GbsBomMapper;
import icu.qx.gbs.domain.GbsBom;
import icu.qx.gbs.service.IGbsBomService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

/**
 * BOM清单Service业务层处理
 *
 * @author yong
 * @date 2024-06-12
 */
@Service
public class GbsBomServiceImpl implements IGbsBomService {
    @Autowired
    private GbsBomMapper gbsBomMapper;

    @Autowired
    private IGbsBomMaterialService gbsBomMaterialService;

    @Autowired
    private PbsProcedureMaterialFeign pbsProcedureMaterialFeign;

    /**
     * 查询BOM清单
     *
     * @return BOM清单
     */
    @Override
    public GbsBom selectGbsBomByBomCode(GbsBom gbsBom) {
        return gbsBomMapper.selectGbsBomByBomCode(gbsBom);
    }

    @Override
    public List<GbsBom> selectGbsBomByPdCode(String bomPdCode) {
        return gbsBomMapper.selectGbsBomByPdCode(bomPdCode);
    }

    /**
     * 查询BOM清单列表
     *
     * @param gbsBom BOM清单
     * @return BOM清单
     */
    @Override
    public List<GbsBom> selectGbsBomList(GbsBom gbsBom) {
        return gbsBomMapper.selectGbsBomList(gbsBom);
    }

    /**
     * 新增BOM清单
     *
     * @param gbsBom BOM清单
     * @return 结果
     */
    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    @Override
    public int insertGbsBom(GbsBom gbsBom, List<GbsBomMaterial> gbsBomMaterials, List<PbsProcedureMaterial> pbsProcedureMaterials) {
        try {
            gbsBom.setCreateBy(SecurityUtils.getUsername());
            gbsBom.setCreateTime(DateUtils.getNowDate());

            if (gbsBomMaterials != null) {
                gbsBomMaterials.forEach(e -> {
                    BigDecimal total = BigDecimal.ZERO;
                    pbsProcedureMaterials.forEach(e1 -> {
                        if (e.getBmMaterialCode().equals(e1.getPdCode())) {
                            total.add(e1.getProcudereMNum());
                        }
                    });
                    e.setBmUse(total);
                    e.setBmBomCode(gbsBom.getBomCode());
                    e.setBmBomVersion(gbsBom.getBomVersion());
                    gbsBomMaterialService.insertGbsBomMaterial(e);
                });
            }

            // 添加工艺路线中工序物料
            pbsProcedureMaterials.forEach(e -> {
                e.setProcedureMBom(gbsBom.getBomCode());
                e.setProcedureMBV(gbsBom.getBomVersion());
            });

            R<Integer> r = pbsProcedureMaterialFeign.add(pbsProcedureMaterials);
            if (r.getData() <= 0) {
                throw new Exception("fail to add materials");
            }

            return gbsBomMapper.insertGbsBom(gbsBom);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return -1;
        }
    }

    /**
     * 修改BOM清单
     *
     * @param gbsBom BOM清单
     * @return 结果
     */
    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    @Override
    public int updateGbsBom(GbsBom gbsBom, List<GbsBomMaterial> gbsBomMaterials, List<PbsProcedureMaterial> pbsProcedureMaterials) {
        try {
            gbsBom.setUpdateBy(SecurityUtils.getUsername());
            gbsBom.setUpdateTime(DateUtils.getNowDate());

            GbsBomMaterial gbsBomMaterial = new GbsBomMaterial();
            gbsBomMaterial.setBmBomCode(gbsBom.getBomCode());
            gbsBomMaterial.setBmBomVersion(gbsBomMaterial.getBmBomVersion());
            gbsBomMaterialService.deleteGbsBomMaterialByBmBomCode(gbsBomMaterial);
            if (gbsBomMaterials != null) {
                gbsBomMaterials.forEach(e -> {
                    e.setBmBomCode(gbsBom.getBomCode());
                    gbsBomMaterialService.insertGbsBomMaterial(e);
                });
            }

            PbsProcedureMaterial pbsProcedureMaterial = new PbsProcedureMaterial();
            pbsProcedureMaterial.setProcedureMBom(gbsBom.getBomCode());
            pbsProcedureMaterial.setProcedureMBV(gbsBom.getBomVersion());
            pbsProcedureMaterial.setPmProuteCode(gbsBom.getBomRoute());
            AjaxResult remove = pbsProcedureMaterialFeign.remove(pbsProcedureMaterial);
            if (remove.get("data") == null) {
                throw new Exception("fail to remove materials");
            }
            if (pbsProcedureMaterials != null) {
                // 添加工艺路线中工序物料
                pbsProcedureMaterials.forEach(e -> {
                    e.setProcedureMBom(gbsBom.getBomCode());
                });
                R<Integer> r = pbsProcedureMaterialFeign.add(pbsProcedureMaterials);
                System.err.println("r data " + r);
                if (r.getData() <= 0) {
                    throw new Exception("fail to add materials");
                }
            }

            int i = gbsBomMapper.updateGbsBom(gbsBom);

            return i;
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return -1;
        }
    }

    /**
     * 批量删除BOM清单
     *
     * @param bomCodes 需要删除的BOM清单主键
     * @return 结果
     */
    @Override
    public int deleteGbsBomByBomCodes(String[] bomCodes) {
        return gbsBomMapper.deleteGbsBomByBomCodes(bomCodes);
    }

    /**
     * 删除BOM清单信息
     *
     * @param bomCode BOM清单主键
     * @return 结果
     */
    @Override
    public int deleteGbsBomByBomCode(String bomCode) {
        return gbsBomMapper.deleteGbsBomByBomCode(bomCode);
    }
}
